﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.DynamicData;

namespace NotAClue.ComponentModel.DataAnnotations
{
    /// <summary>
    /// Allows mapping of page action to other 
    /// actions on a table by table basis
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class PageActionMappingAttribute : Attribute
    {
        /// <summary>
        /// Gets or sets the action mapping parameters.
        /// </summary>
        /// <value>The mappings.</value>
        public Dictionary<String, String> MappingParameters { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="PageActionMappingAttribute"/> class.
        /// </summary>
        /// <param name="mappings">The mappings.</param>
        public PageActionMappingAttribute(params Object[] mappingParameters)
        {
            SetMappings(mappingParameters);
        }

        /// <summary>
        /// Converts the mapping parameters from an object array to a dictionary.
        /// </summary>
        /// <param name="mappingParameters">The mapping parameters.</param>
        private void SetMappings(Object[] mappingParameters)
        {
            // initialize dictionary
            MappingParameters = new Dictionary<String, String>();

            // make sure we some parameters
            if ((mappingParameters != null) && (mappingParameters.Length != 0))
            {
                // check that they are in pairs
                if ((mappingParameters.Length % 2) != 0)
                    throw new ArgumentException(
                        "PageActionMappingAttribute mapping parameters needs an even number of parameters");

                // loop through each pair
                for (int i = 0; i < mappingParameters.Length; i += 2)
                {
                    var keyObject = mappingParameters[i];
                    var value = mappingParameters[i + 1];

                    // check there is a valid key
                    if (keyObject == null)
                        throw new ArgumentException("PageActionMappingAttribute a key is null");

                    // check it is a PageTemplate
                    if (!(keyObject is PageTemplate))
                        throw new ArgumentException("PageActionMappingAttribute keys must be a PageTemplate");

                    // check value is of type string
                    if (!(value is String) && !(value is PageTemplate))
                        throw new ArgumentException("PageActionMappingAttribute value must be a string or PageTemplate enum");

                    // get the key(s)
                    var keys = ((PageTemplate)keyObject).ToString().Split(new String[] { ", " }, StringSplitOptions.RemoveEmptyEntries);

                    // check to see if we have OR'ed enum values
                    if (keys.Length > 1)
                    {
                        // loop through each enum value
                        foreach (var key in keys)
                        {
                            // make sure we don't have any duplicates.
                            if (this.MappingParameters.ContainsKey(key))
                                throw new ArgumentException(String.Format("PageActionMappingAttribute has duplicate key:{0}", key));

                            // add entries to dictionary
                            this.MappingParameters.Add(key, value.ToString());
                        }
                    }
                    else
                        // add entries to dictionary
                        this.MappingParameters.Add(keys[0], value.ToString());
                }
            }
        }
    }
}